package com.tiheima.manager;

import com.tiheima.config.MinIOConfig;
import com.tiheima.model.result.Result;
import com.tiheima.utils.MinIOUtils;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashSet;

@Component
public class MinIOManager {

    // 最大文件限制 2M
    private final long MAX_FILE = 2 * 1048576;
    // 允许上传的文件类型
    private final String[] ALLOW_FILE_TYPE = {"image/png", "image/jpeg", "image/jpg"};

    @Resource
    private MinIOConfig minIOConfig;

    /**
     * 根据用户id上传图片
     * @param file 要上传的图片文件
     * @return 上传后的图片地址
     * @throws Exception
     */
    public Result<?> upload(MultipartFile file) throws Exception {
        String verify = verify(file);
        if (!verify.equals(file.getOriginalFilename())) {
            return Result.error(verify);
        }
        String fileName = verify;
        String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        fileName = format + "-" + fileName;

        // 通过流上传文件
        MinIOUtils.uploadFile(minIOConfig.getBucketName(), fileName, file.getInputStream());

        return Result.success(minIOConfig.getFileHost() + "/"
                + minIOConfig.getBucketName() + "/"
                + fileName);
    }



    /**
     * 根据用户id上传图片
     * @param file 要上传的图片文件
     * @param userId 做此操作的用户id
     * @return 上传后的图片地址
     * @throws Exception
     */
    public Result<?> uploadOnUserId(MultipartFile file, String userId) throws Exception {
        String verify = verify(file,userId);
        if (!verify.equals(file.getOriginalFilename())) {
            return Result.error(verify);
        }
        String fileName = verify;
        String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        fileName = userId  + "/" + format + "-" + fileName;

        // 通过流上传文件
        MinIOUtils.uploadFile(minIOConfig.getBucketName(), fileName, file.getInputStream());

        return Result.success(minIOConfig.getFileHost() + "/"
                + minIOConfig.getBucketName() + "/"
                + fileName);
    }

    /**
     * 删除图片
     * @Param url 图片地址
     */
    public void deletes(ArrayList<String> urlList) {
        // 移除urlList中的空数据
        urlList.removeIf(StringUtils::isBlank);
        if (urlList.isEmpty()) return;
        // 移除urlList中的重复数据
        ArrayList<String> distinctList = new ArrayList<>(new HashSet<>(urlList));
        // 过滤路径头
        for (int i = 0; i < distinctList.size(); i++) {
            String url = distinctList.get(i);
            String host = minIOConfig.getFileHost() + "/" + minIOConfig.getBucketName() + "/";
            if (url.startsWith(host)) {
                distinctList.set(i, url.substring(host.length()));
            }
        }
        MinIOUtils.removeFiles(minIOConfig.getBucketName(), distinctList);
    }

    /**
     * 校验文件，若校验无误则返回文件名。
     * @param file
     * @param userId
     * @return
     * @throws Exception
     */
    String verify(MultipartFile file, String userId) {
        if (StringUtils.isBlank(userId)) {
            return "文件上传失败，请传入用户id";
        }
        return verify(file);
    }

    /**
     * 校验文件，若校验无误则返回文件名。
     * @param file
     * @return
     * @throws Exception
     */
    String verify(MultipartFile file) {
        //1.检查文件是否为空
        if (file.isEmpty()) {
            return "文件上传失败，空文件";
        }
        //2.获取文件名
        String fileName = file.getOriginalFilename();
        if (StringUtils.isBlank(fileName)) {
            return "文件上传失败，格式错误";
        }
        //3.检查文件大小
        long fileSize = file.getSize();
        if (fileSize > MAX_FILE) {
            return "文件上传失败，图片过大";
        }
        //4.检查文件类型
        String contentType = file.getContentType();
        if (StringUtils.isBlank(contentType)) {
            return "文件上传失败，格式错误";
        }
        for (String s : ALLOW_FILE_TYPE) {
            if (!(s.equals(contentType))) {
                return "文件上传失败，文件类型错误";
            }
        }
        return fileName;
    }
}
